#include <stdio.h>
#include <pthread.h>
#include "common/console.h"
#include "common/cJSON.h"
#include <stdio.h>
#include <unistd.h>
#include "userLog.h"
#include "pal/vz_app.h"
#include <memory.h>
#include "pal/vz_app_common.h"
#include "pal/vz_protocol.h"

static unsigned char gnSeq = 0;

// static const uint8_t ENABLE_PUSH_CMD[] = "{\"cmd\":\"ivsresult\",\"enable\":true, \"format\":\"bin\",\"image\":true,\"image_type\": 2}";
// static const uint8_t DISABLE_PUSH_CMD[] = "{\"cmd\":\"ivsresult\",\"enable\":false, \"format\":\"bin\",\"image\":true,\"image_type\": 2}";

//函数声明
int VZ_GenCmdGetSn(char *pOut, int nLen);
int VZ_JsonGetSn(const char *pIn, int nLen, char *pSn, int nSnBufLen);
int VZ_JsonParseId(const char *pIn, int nLen, char *pId, int nIdBufLen);

static unsigned char _VZ_GetSeq(void)
{
	gnSeq = gnSeq % 255;
	return gnSeq++;
}

static inline unsigned int VZ_SetDataLen(unsigned int unLen)
{
	return htonl(unLen);
}
static inline int VZ_InitHead(VZ_HEAD_T *pHead, unsigned char ucType, unsigned char seq, unsigned int unDataLen)
{
	if (pHead)
	{
		pHead->cMagic1 = 'V';
		pHead->cMagic2 = 'Z';
		pHead->ucPacketType = ucType;
		pHead->ucSeq = seq;
		pHead->unDataLen = unDataLen;
		return 0;
	}
	return -1;
}

int32_t VZ_GenCmdHeartBeat(char *pOut, int nLen)
{
	VZ_PACKET_T *pPack;
	char cmd[128];
	int nBodyLen = 0;

	if (pOut == NULL)
	{
		LOG_ERROR("buf is null");
		return -1;
	}

	memset((void *)cmd, 0, sizeof(cmd));
	pPack = (VZ_PACKET_T *)cmd;
	nBodyLen = 0;
	unsigned char seq = _VZ_GetSeq();
	VZ_InitHead(&pPack->stHead, VZ_DATA_TYPE_HB, seq, VZ_SetDataLen(nBodyLen));
	if ((nBodyLen + sizeof(VZ_HEAD_T)) > nLen)
	{
		LOG_ERROR("cmd out buf is not enough buf");
		return -1;
	}

	memcpy((void *)pOut, (void *)cmd, nBodyLen + sizeof(VZ_HEAD_T));

	return (nBodyLen + sizeof(VZ_HEAD_T));
}

int32_t VZ_GenCmd_set_ivsresult(uint8_t *pOut, int32_t nLen, bool enable)
{
	VZ_PACKET_T *pPack;
	uint8_t cmd[128];
	int nBodyLen = 0;

	if (pOut == NULL)
	{
		LOG_ERROR("buf is null");
		return -1;
	}

	memset((void *)cmd, 0, sizeof(cmd));
	pPack = (VZ_PACKET_T *)cmd;
	nBodyLen = sprintf(pPack->acData, "{\"cmd\":\"ivsresult\",\"enable\":%s, \"format\":\"%s\",\"image\":true,\"image_type\":2}",
					   enable == true ? "true" : "false", //
					   "bin");							  //
	unsigned char seq = _VZ_GetSeq();
	VZ_InitHead(&pPack->stHead, VZ_DATA_TYPE_JSON, seq, VZ_SetDataLen(nBodyLen));

	if ((nBodyLen + sizeof(VZ_HEAD_T)) > nLen)
	{
		LOG_ERROR("cmd out buf is not enough buf");
		return -1;
	}

	memcpy((void *)pOut, (void *)cmd, nBodyLen + sizeof(VZ_HEAD_T));
	// hzlog_info(userLog, pOut, nBodyLen + sizeof(VZ_HEAD_T));

	return (nBodyLen + sizeof(VZ_HEAD_T));
}

static const uint8_t TRIGGER_CMD[] = "{\"cmd\":\"trigger\"}";
int VZ_GenCmdTrigger(uint8_t *pOut, int32_t nLen)
{
	VZ_PACKET_T *pPack;
	uint8_t cmd[128];
	int nBodyLen = 0;

	if (pOut == NULL)
	{
		LOG_ERROR("buf is null");
		return -1;
	}

	memset((void *)cmd, 0, sizeof(cmd));
	pPack = (VZ_PACKET_T *)cmd;
	nBodyLen = sprintf(pPack->acData, "%s", TRIGGER_CMD);
	unsigned char seq = _VZ_GetSeq();
	VZ_InitHead(&pPack->stHead, VZ_DATA_TYPE_JSON, seq, VZ_SetDataLen(nBodyLen));

	if ((nBodyLen + sizeof(VZ_HEAD_T)) > nLen)
	{
		LOG_ERROR("cmd out buf is not enough buf");
		return -1;
	}

	memcpy((void *)pOut, (void *)cmd, nBodyLen + sizeof(VZ_HEAD_T));
	// hzlog_info(userLog, pOut, nBodyLen + sizeof(VZ_HEAD_T));

	return (nBodyLen + sizeof(VZ_HEAD_T));
}

int VZ_GenCmdGetSnapShot(uint8_t *pOut, int32_t nLen)
{
	VZ_PACKET_T *pPack;
	uint8_t cmd[128];
	int nBodyLen = 0;

	if (pOut == NULL)
	{
		LOG_ERROR("buf is null");
		return -1;
	}

	memset((void *)cmd, 0, sizeof(cmd));
	pPack = (VZ_PACKET_T *)cmd;
	nBodyLen = sprintf(pPack->acData, "{\"cmd\":\"%s\"}", VZ_CMD_GET_SNAP_SHOT);
	unsigned char seq = _VZ_GetSeq();
	VZ_InitHead(&pPack->stHead, VZ_DATA_TYPE_JSON, seq, VZ_SetDataLen(nBodyLen));

	if ((nBodyLen + sizeof(VZ_HEAD_T)) > nLen)
	{
		LOG_ERROR("cmd out buf is not enough buf");
		return -1;
	}

	memcpy((void *)pOut, (void *)cmd, nBodyLen + sizeof(VZ_HEAD_T));
	// hzlog_info(userLog, pOut, nBodyLen + sizeof(VZ_HEAD_T));

	return (nBodyLen + sizeof(VZ_HEAD_T));
}

static int VZ_BinParseIvsresult(char *pData, int nLen)
{
	VZ_PACKET_T *pPack = NULL;
	int nTotalLen = 0;		/*整包大小*/
	int nResultDiscLen = 0; /*识别结构体大小*/
	int nImg1Len = 0;		/*大图大小*/
	int nImg2Len = 0;		/*小图大小*/

	if (nLen <= sizeof(VZ_HEAD_T))
	{
		LOG_ERROR("invalid data");
		return -1;
	}

	nTotalLen = nLen;

	// disc
	pPack = (VZ_PACKET_T *)pData;
	if (pPack == NULL)
	{
		LOG_ERROR("ptr is null");
		return -1;
	}
	if (pPack->stHead.cMagic1 != 'I' || pPack->stHead.cMagic2 != 'R')
	{
		LOG_ERROR("magic not valid");
		return -1;
	}
	if (pPack->stHead.ucPacketType != 1)
	{
		LOG_ERROR("invalid packet type, should be 1 for img param:%d", pPack->stHead.ucPacketType);
		return -1;
	}

	nResultDiscLen = pPack->stHead.unDataLen;
	if (nResultDiscLen > sizeof(TH_PlateResult))
	{
		LOG_ERROR("invalid disc len:%d", nResultDiscLen);
		return -1;
	}
	// img1
	pPack = (VZ_PACKET_T *)(pData + sizeof(VZ_HEAD_T) + nResultDiscLen);
	if (pPack == NULL)
	{
		LOG_ERROR("ptr is null");
		return -1;
	}

	if (pPack->stHead.cMagic1 != 'I' || pPack->stHead.cMagic2 != 'R')
	{
		LOG_ERROR("magic not valid");
		return -1;
	}
	nImg1Len = pPack->stHead.unDataLen;
	LOG_DEBUG("图片1大小: %d bytes", nImg1Len);
	if (nImg1Len > VZ_IMG1_SIZE)
	{
		LOG_ERROR("invalid img1 len:%d", nImg1Len);
		return -1;
	}

	// img2
	if ((nTotalLen - nResultDiscLen - nImg1Len - sizeof(VZ_HEAD_T) * 2) > 0)
	{
		pPack = (VZ_PACKET_T *)(pData + sizeof(VZ_HEAD_T) * 2 + nResultDiscLen + nImg1Len);
		if (pPack == NULL)
		{
			LOG_ERROR("ptr is null");
			return -1;
		}
		if (pPack->stHead.cMagic1 != 'I' || pPack->stHead.cMagic2 != 'R')
		{
			LOG_ERROR("magic not valid");
			return -1;
		}
		nImg2Len = pPack->stHead.unDataLen;
		LOG_DEBUG("图片2大小 :%d bytes", nImg2Len);
		if (nImg2Len > VZ_IMG2_SIZE)
		{
			LOG_ERROR("invalid img2 len:%d", nImg2Len);
			return -1;
		}
	}
	LOG_DEBUG("推送摄像枪识别结果");

	return 0;
}
